package com.lc.rocketmq.service;

import com.lc.rocketmq.po.Goods;
import com.lc.rocketmq.po.Order;
import com.lc.rocketmq.vo.SeckillVo;
import com.lc.rocketmq.vo.WaitingPayVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import sun.rmi.runtime.Log;

import java.util.concurrent.locks.LockSupport;

/**
 * @author liuc
 * @date 2021/8/21
 * @description
 **/
@Slf4j
@Component
public class SeckillConsumeService {
    @Autowired
    private GoodsService goodsService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private SeckillService seckillService;
    @Autowired
    private SeckillSender seckillSender;
    @Autowired
    private RedisService redisService;

    @Transactional(rollbackFor = Exception.class)
    public void consume(SeckillVo vo){
        //防止重复消费
        Order exists = orderService.get(vo.getUserId(), vo.getGoodsId());
        //没有订单或者订单失效过期
        if(exists == null){
            //1.生成订单
            Order order = orderService.add(vo.getUserId(), vo.getGoodsId());
            //2.扣减库存
            boolean suc = goodsService.reduceStock(vo.getGoodsId(),-1);
            //3.告知订单生成成功
            if(suc){
                seckillService.orderSuccess(vo,order.getId());
                //4.同时发送一条延时消息用于检测支付超时
                WaitingPayVo waitingPayVo = new WaitingPayVo();
                waitingPayVo.setOrderId(order.getId());
                waitingPayVo.setUserId(vo.getUserId());
                waitingPayVo.setGoodsId(vo.getGoodsId());
                seckillSender.waitingPay(waitingPayVo);
            }else{
                orderService.fail(order.getId());
            }
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void payTimeout(WaitingPayVo vo){
        if(vo.getOrderId() != null){
            log.info("订单过期消息消费,orderId:{}",vo.getOrderId());
            //设置过期支付, 乐观锁更新, 可能设置过期的时候刚刚好被支付赶上, 看谁先更新
            boolean b = orderService.timeout(vo.getOrderId());
            if(b){
                log.info("订单过期,更新状态,orderId:{}",vo.getOrderId());
                //更新库存
                boolean f = goodsService.reduceStock(vo.getGoodsId(), 1);
                //更新缓存
                if(f){
                    Goods goods = goodsService.find(vo.getGoodsId());
                    seckillService.recovery(vo.getUserId(),vo.getGoodsId(),goods.getStock());
                }else{
                    //更新失败的话,订单已经是其他的状态了
                    //
                    log.info("order:{} status is not new",vo.getOrderId());
                }
            }
        }
    }
}
